pin-diary-6 pull:1
pin-diary-6へのPR
/Mijinko-other/pin-diary-6-sd-dev 2022-12-31
タイトルをpin-diary-6 pull#1からpin-diary-6 pull:1へ変更
#が入っているとハッシュタグを作成できなくなってしまうため
pin-diary-6の以下のバグの修正を行いましたMijinko_SD.icon
既にページが作成されて書き込みされていた場合にテンプレートフォーマットを挿入すると、空行より下が分断されてしまうバグ
これはおそらく、ページを書き込んだ際に機能する空行承り太郎の空行を、テンプレートの一部として誤認してしまうのが原因
テンプレートが分断されていた場合は、固まったテンプレートを新たに挿入する形で解決しました
これ以外の解決策としては、テンプレートの一部が欠落していた場合、既存のテンプレート行(空行除く)に欠落しているテンプレートを追記する処理が考えられると思います
修正後のソースコード
/Mijinko-other/pin-diary-6-sd-dev 2022-12-04
6依存(未変更)にカテゴライズされているソースファイル以外は書き換えてあります
修正ありがとうございますtakker.icon
返信遅れてすみません
お気になさらずMijinko_SD.icon
pin-diary-5
修正反映は少々お待ち下さい
やること
diff確認
$ curl https://scrapbox.io/api/code/villagepump/pin-diary-5/util.ts > util_old.ts && curl https://scrapbox.io/api/code/Mijinko-other/pin-diary-6-sd-dev_2022-12-04/util.ts > util.ts && diff -y util_old.ts util.ts
arrow functionに書き換え
依存関係の見直し
pin-diary-6からpin-diary-5への依存をなくす
違うversionを参照しているとややこしい
今までのversionをgithubにサルページしておこうかな
/Mijinko-other/pin-diary-5のutil.tsの解析#638b7d3d7838e30000ca3c5d
前後に空白が混じっているだけで違う行判定されたくない……からかな?takker.icon
なんとなく入れただけだと思われる
よくわからなかったですが、一応修正後のソースコードでも.trim()して判別する仕様にしてありますMijinko_SD.icon
はーいtakker.icon
2022-12-21完全に忘れてた()takker.icon
でもinboxみたらちゃんとメモしてあったからヨシ!.icon
来週から授業ないのでそのへんでやります~
修正した後から思ったのですが、本当にこの仕様(フォーマット挿入関連の仕様)で良かったのかなーってちょっと思い始めているMijinko_SD.icon
フォーマットの文章の下に箇条書きで追記しにくくなった
2022/12/06#638e88381280f00000fc1813
2022/12/13#639890345e90c0000032f3b4
人間の手が加えられないというところから、/shokai/WOM(Write Only Member)に書かれているような悪い特徴が出てしまっている気がする
2022/12/31 17:30:53 修正しましたMijinko_SD.icon
/Mijinko-other/pin-diary-6-sd-dev 2022-12-31
結局のところ、「テンプレート行が分断されるのは許容するが、テンプレート行が1行でも欠損していた場合は新たに挿入し直す」という仕様になりました
前回のdevのソースコードからの差分としては、1行コメントアウトしただけ
単体テストを書いて確認しますtakker.icon
変更点はpin-diary-5のformat.tsおよびそれが依存しているmodulesのみ
なのでformat.tsとutil.tsの単体テストだけを書けばいい
$ deno test -r=https://scrapbox.io https://scrapbox.io/api/code/villagepump/pin-diary-6_pull%231/format_test.ts https://scrapbox.io/api/code/villagepump/pin-diary-6_pull%231/util_test.ts
pin-diaryをそろそろgithubに移そうか考えているtakker.icon
古い変更を言及するのがScrapboxだときつい
例えば今(2023-01-07 14:08:12 )、passさせた単体テストの結果について色々書き込んでいるが、ロジックを修正して単体テストの結果が変わると、コメントの意味がわからなくなる
code:format_test.ts
import { patchTemplate } from "./format.ts";
import { assertEquals } from "./deps_test.ts";
Deno.test("patchTemplate()", async (t) => {
await t.step("その1", () => {
const headers = [
"header start",
"header content",
"",
"header end",
];
const lines = [
"何か",
"aaa",
"header content",
" コメントが書いてあるかも",
"header end modified",
"",
"本文とか",
"おしまい",
"footer end",
" ↑footerの残骸",
];
const footers = [
"footer start",
"footer content",
"footer end",
];
assertEquals<string[]>(patchTemplate(lines, headers, footers), [
"header start",
"header content",
"",
"header end",
"",
"何か",
"aaa",
"header content",
" コメントが書いてあるかも",
"header end modified",
うーん、ここのheaderが新規追加されちゃうかあtakker.icon
(まだちゃんとコード読んでいないので、どういう条件でいい感じにformatが復元されるか理解していない)
code:format_test.ts
"",
"本文とか",
"おしまい",
"footer end",
" ↑footerの残骸",
"",
"footer start",
"footer content",
"footer end",
ここも、合体されてほしいtakker.icon
code:format_test.ts
]);
});
});
code:util_test.ts
import { patchLines } from "./util.ts";
import { assertEquals } from "./deps_test.ts";
Deno.test("patchLines()", async (t) => {
await t.step("その1", () => {
const template = [
"template start",
"template template",
"template end",
];
const lines = [
"何か",
"aaa",
"template template",
" コメントが書いてあるかも",
"template end modified",
"",
"本文とか",
"おしまい",
];
assertEquals<string[]>(patchLines(lines, template), [
"template start",
"template template",
"template end",
"何か",
"aaa",
"template template",
" コメントが書いてあるかも",
"template end modified",
"",
"本文とか",
"おしまい",
]);
});
});
code:deps_test.ts
export * from "https://deno.land/std@0.171.0/testing/asserts.ts";
code:format.ts
import { findSplitIndex, patchLines } from "./util.ts";
// linesにタイトルを入れないように
export const patchTemplate = (
lines: string[],
headers: string[],
footers: string[],
): string[] => {
// headerとfooterに相当する行を補う
let bodies: string[] = lines;
bodies = patchLines(bodies, headers, "head");
bodies = patchLines(bodies, footers, "tail");
// headerとfooterの間に余裕をもたせる
const headerEnd = findSplitIndex(bodies, headers);
const footerEnd = findSplitIndex(bodies, footers);
if (headerEnd === null || footerEnd === null) {
// バグってテンプレの挿入がうまくいかなかったら諦める
console.log(
"format.tsのコードがバグったためtemplateの挿入を諦めました。\n" +
headerEnd: ${headerEnd}, footerEnd: ${footerEnd},
);
return lines;
}
const footerStart = footerEnd + 1 - footers.length;
return [
...bodies.slice(0, headerEnd + 1),
"",
...bodies.slice(headerEnd + 1, footerStart).join("\n").trim().split("\n"),
"",
...bodies.slice(footerStart),
];
};
code:util.ts
export const patchLines = (
lines: string[],
appends: string[],
position: "head" | "tail" = "head",
): string[] => {
let appendsIndex = 0;
for (const line of lines) {
if (line.trim() == appendsappendsIndex.trim()) {
if (appendsIndex == appends.length - 1) {
// appendsと完全に一致するパターンが発見されたので行を挿入せずに終了する
return lines;
}
++appendsIndex;
} else {
// 何もしない
// appendsIndex = 0;
}
}
// 一致するパターンが見つからなかった場合はappendsを挿入する
switch (position) {
case "head":
return ...appends, ...lines;
case "tail":
return ...lines, ...appends;
}
};
/** queryに合致するlinesの終了行を返す */
export const findSplitIndex = (
lines: string[],
query: string[],
): number | null => {
let queryCount = 0;
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
if (lineslineIndex.trim() == queryqueryCount.trim()) {
if (queryCount == query.length - 1) return Number(lineIndex);
++queryCount;
}
}
return null;
};